<?php
/*
 * Link: http://www.white-hat-web-design.co.uk/articles/php-image-resizing.php
 * - added: the following function
 * - __construct
 * - set_param - different parameter for different mode
 * - crop
 * - composite_background
 */

class Imaging {
  protected $image; // assessible by subclass 
  protected $image_type;
  protected $resized = 0;

  function __construct($filename, $h_param=array()){
  	$this->load($filename);
  	$this->set_param($h_param); 
  }

  public function load($filename) {
    $image_info = getimagesize($filename);
    $this->image_type = $image_info[2];
    if( $this->image_type == IMAGETYPE_JPEG ) {
     $this->image = imagecreatefromjpeg($filename);
    } elseif( $this->image_type == IMAGETYPE_GIF ) {
     $this->image = imagecreatefromgif($filename);
    } elseif( $this->image_type == IMAGETYPE_PNG ) {
     $this->image = imagecreatefrompng($filename);
    }
  }

  // crop / zoon / bgcolor etc parameter
  public function set_param($h_param=array()){
    //override by child
  }

  // for saving cropping parameters to database
  // only support 'as_string' mode first
  function get_param($mode){
  	if ($mode != 'as_string') return '';
  	//override by child
  	return '';
  }

	public function save($filename, $ext='jpg', $compression=75, $permissions=null) {
    $image_type=$this->extension_to_type($ext);
	  if( $image_type == IMAGETYPE_JPEG ) {
	    imagejpeg($this->image,$filename,$compression);
	  } elseif( $image_type == IMAGETYPE_GIF ) {
	    imagegif($this->image,$filename);
	  } elseif( $image_type == IMAGETYPE_PNG ) {
	    imagepng($this->image,$filename);
	  }
	  if( $permissions != null) {
	     chmod($filename,$permissions);
	  }
	  return $this->get_param('as_string');
	}
 
  function extension_to_type($ext){
    if ($ext == 'jpg' || $ext =='jpeg') return IMAGETYPE_JPEG;
    if ($ext == 'gif') return IMAGETYPE_GIF;
    if ($ext == 'png') return IMAGETYPE_PNG;
 
  }
 


	public function output($image_type=IMAGETYPE_JPEG) {
	  if( $image_type == IMAGETYPE_JPEG ) {
	     imagejpeg($this->image);
	  } elseif( $image_type == IMAGETYPE_GIF ) {
	     imagegif($this->image);
	  } elseif( $image_type == IMAGETYPE_PNG ) {
	     imagepng($this->image);
	  }
	}


	protected function get_width() {
	  return imagesx($this->image);
	}


	protected function get_height() {
	  return imagesy($this->image);
	}

  protected function get_dimension(){
  	$w = imagesx($this->image);
  	$h = imagesy($this->image);
  	return $w.'x'.$h;
  }

	protected function resize_to_height($height) {
		$ratio = $height / $this->get_height();
	  $width = $this->get_width() * $ratio;
	  return $this->_resize($width,$height);
	}
	
	protected function resize_to_width($width) {
	  $ratio = $width / $this->get_width();
	  $height = $this->get_height() * $ratio;
	  return $this->_resize($width,$height);
	}

	protected function scale($scale) {
	  $w = $this->get_width()  * $scale/100;
	  $h = $this->get_height() * $scale/100;
	  return $this->_resize($w,$h);
	}
	
	// resize to specified size, without checking aspect ratio
	protected function _resize($width,$height) {
	  $new_image = imagecreatetruecolor($width, $height);
	  imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->get_width(), $this->get_height());
	  $this->image = $new_image;
	  #echo("Rsized to $width  $height\n");
	  return array($width, $height);
	}

	// resize to specified size, without checking aspect ratio
	protected function crop($top, $left, $w, $h){
	  #echo("Crop $top, $left, $width, $height\n");
	  $new_image = imagecreatetruecolor($w, $h);
	  imagecopyresized($new_image, $this->image, 0, 0, 
	                   $top, $left, $w, $h, $w, $h);
	  $this->image = $new_image;
	}

  
  public function debug_image($img){
  	echo("Image w: ".imagesx($img)."\n");
  	echo("Image h: ".imagesy($img)."\n");
  }


  /* add a background to the current image
   * 
   */ 
  public function composite_background($width, $height, $color){
  	#echo("Add background: $width $height $color\n");
  	$src_w = $this->get_width();
    $src_h = $this->get_height();
    
    if ($width < $src_w || $height < $src_h){
    	#echo("Background is smaller than source\n");
    	return;
    }
  	$bg_img = $this->create_background_image($width, $height, $color);
  	
    $dst_x = ($width  - $src_w)/2;
    $dst_y = ($height - $src_h)/2;
    #echo("dst_x: $dst_x dst_y $dst_y, $width, $height\n");
    imagecopymerge($bg_img, $this->image, 
       $dst_x, $dst_y , 
       0, 0 , 
       $src_w, $src_h,
       100);
    $this->image = $bg_img; 	
  }
  
  /* create an background image
   */
  private function create_background_image($width, $height, $color){
  	#echo("Create background image $width $height $color\n");
    $bg_img = ImageCreateTrueColor($width, $height);
    list($red, $green, $blue) = $this->rgb_to_int($color);
    $bgcolor = ImageColorAllocate($bg_img, $red, $green, $blue);
    ImageFilledRectangle($bg_img, 0, 0, $width, $height, $bgcolor);
    
    //imagedestroy($im);
    return $bg_img;
  }
  
  
  /* group of folder for set of 
   * auto select an appropiate from folder
   * @param  $x_ratio  max ratio width of the watermark  / width of image
   * @param  $x_ratio  max ratio height of the watermark / height of image
   * @param  $opacity  opacity of watermark
   * @param  $x_pos: 0-100, 0 left <-> right 100
   * @param  $y_pos: 0-100, 0 top  <-> bottom 100
   */
  public function auto_watermark($folder, $opacity=50, $x_ratio=30, $y_ratio=30, $x_pos=100, $y_pos=100){
  	$wm_max_w = $this->get_width() * $x_ratio / 100;
    $wm_max_h = $this->get_height() * $x_ratio / 100;
    
  	if (substr($folder, -1) != '/') $folder .= '/';              # add trailing slash     	
  	$glob_folder = $folder.'*.png';
  	$watermark_files = glob($glob_folder);
  	rsort($watermark_files);
  	
  	//echo("$wm_max_w  $wm_max_h\n");
  	
  	$wm_matched_file = '';
  	foreach ($watermark_files as $wm_fullfile){ // assume it return in order?
  		$filename = basename($wm_fullfile, '.png');
  		list($wm_w, $wm_h) = explode('x', $filename);
  		//echo("  $wm_w  $wm_h\n"); 
  		if ($wm_max_w >= $wm_w && $wm_max_h >= $wm_h) {
  		  //echo("$filename $wm_w, $wm_h\n");
  		  $wm_matched_file = $wm_fullfile;
  		  break;
  		} 
  		//echo("TOO Big $filename $wm_w, $wm_h\n");
  		
  	}
  	
  	if (! empty($wm_matched_file)){
  		$this->watermark($wm_matched_file, $opacity, $x_pos, $y_pos);
  	}
  	
//    // another way to loop through all files  	
//    foreach (new DirectoryIterator($folder) as $fileInfo) {
//      if($fileInfo->isDot()) continue;
//      echo $fileInfo->getFilename() . "<br>\n";
//    }  	
  }
  
  /* @param $wm_path: full path of watermark image file
   * @param $x_pos: 0-100, 0 left <-> right 100
   * @param $y_pos: 0-100, 0 top  <-> bottom 100
   */
  protected function watermark($wm_path, $opacity=50, $x_pos=100, $y_pos=100){
  	$width  = $this->get_width();
    $height = $this->get_height();
    
    $wm_img = imagecreatefrompng($wm_path);
    imagealphablending($wm_img, true);
  	$wm_w   = imagesx($wm_img);
  	$wm_y   = imagesy($wm_img);
  	
  	$x_pos /=100;
  	$y_pos /=100;
  	
    $dst_x = ($width  - $wm_w)/$x_pos;
    $dst_y = ($height - $wm_y)/$y_pos;
    
    #echo("dst_x: $dst_x dst_y $dst_y, $width, $height\n");
    imagecopymerge($this->image, $wm_img,
       $dst_x, $dst_y , 
       0, 0 , 
       $width, $height,
       $opacity);     	  	
  }
  
  /* Color in format of: #FFEEDD or BBAA99
   */
  function rgb_to_int($color){
  	if ( substr($color, 0, 1) == '#' ){
  	  // put values into an easy-to-use array
      $red   =  substr($color, 1, 2) ;
      $green =  substr($color, 3, 2) ;
      $blue  =  substr($color, 5, 2) ;
    } else {
      // put values into an easy-to-use array
      $red   =  substr($color, 0, 2) ;
      $green =  substr($color, 2, 2) ;
      $blue  =  substr($color, 4, 2) ;    	
    }
  	return array(hexdec($red),hexdec($green),hexdec($blue));
  }
  
//  function color_mkwebsafe ( $in )
//	{
//    // put values into an easy-to-use array
//    $vals['r'] = hexdec( substr($in, 0, 2) );
//    $vals['g'] = hexdec( substr($in, 2, 2) );
//    $vals['b'] = hexdec( substr($in, 4, 2) );
//
//    // loop through
//    foreach( $vals as $val )
//    {
//        // convert value
//        $val = ( round($val/51) * 51 );
//        // convert to HEX
//        $out .= str_pad(dechex($val), 2, '0', STR_PAD_LEFT);
//    }
//
//    return $out;
//	}
  
  
 

}
?>